home *** CD-ROM | disk | FTP | other *** search
- /* Standard C Include files */
- /* #include "CType.h" */
- /* #include "ErrNo.h" */
- /* #include "FCntl.h" */
- /* #include "IOCtl.h" */
- /* #include "Math.h" */
- /* #include "SetJmp.h" */
- /* #include "Signal.h" */
- /* #include "StdIO.h" */
- /* #include "String.h" */
-
- /* Primary Interface Files */
- #include "Types.h"
- /* #include "Resources.h" */
- #include "Quickdraw.h"
- #include "Windows.h"
- /* #include "OSUtils.h" */
-
- /* Commonly Included files */
- /* #include "ToolUtils.h" */
- /* #include "TextEdit.h" */
- /* #include "Controls.h" */
-
- /* Other Interface files */
- /* #include "AppleTalk.h" */
- /* #include "CursorCtl.h" */
- /* #include "Desk.h" */
- /* #include "DeskBus.h" */
- /* #include "Devices.h" */
- /* #include "Dialogs.h" */
- /* #include "DiskInit.h" */
- /* #include "Disks.h" */
- /* #include "ErrMgr.h" */
- #include "Errors.h"
- /* #include "Events.h" */
- #include "Files.h"
- /* #include "Fonts.h" */
- /* #include "Graf3D.h" */
- /* #include "Lists.h" */
- #include "Memory.h"
- /* #include "Menus.h" */
- #include "Packages.h"
- /* #include "Palette.h" */
- /* #include "Perf.h" */
- /* #include "Picker.h" */
- /* #include "Printing.h" */
- /* #include "Retrace.h" */
- /* #include "ROMDefs.h" */
- /* #include "SANE.h" */
- #include "Scrap.h"
- /* #include "Script.h" */
- /* #include "SCSI.h" */
- /* #include "SegLoad.h" */
- /* #include "Serial.h" */
- /* #include "Slots.h" */
- /* #include "Sound.h" */
- /* #include "Start.h" */
- /* #include "Strings.h" */
- /* #include "Time.h" */
- /* #include "Traps.h" */
- /* #include "Values.h" */
- /* #include "VarArgs.h" */
- /* #include "Video.h" */
-
- /* Application-specific Include files */
- #include "::TiffLibrary:TIFFLib.h"
- #include "sample.h"
- #include "messages.h"
-
- static Ptr SetIDPtr();
- static void CleanUp();
- static void InitID();
-
- #define MAXIMAGESIZE 0x8000 /* Limit images to 32K for now */
- #define INFINITY 0x4000000 /* TIFF Spec says 2**32-1 but this is big enough */
-
- /*
- * Read in an image from a TIFF format file. As the code demonstrates, we
- * do not read in very complicated images. We read in a number of tags,
- * and reject the image as an unsuitable tiff file if any of several
- * conditions exist. We do not read in images that have more than one bit
- * of image data per pixel. We do not scale images. Of those simple images
- * that we do read, we will only read the first 32k of that image.
- */
- Boolean ReadTiff(refNum, myBitMapPtr)
- Int16 refNum;
- BitMap *myBitMapPtr;
- {
- Handle listH;
- Boolean oddRowBytes;
- Int8 dummy;
- Int16 byteOrder,
- rowBytes,
- scrnHRes,
- scrnVRes;
- Int32 tagOffset,
- nextDirOffset,
- nextFileFree, /* next free location in output file */
- dirOffset,
- rowsPerImage,
- count,
- size;
- Rational xRes,
- yRes;
- Rect imageRect;
- TiffDirEntry tagDirEntry;
- id id; /* image description */
-
- InitID(&id);
- ScreenRes(&scrnHRes, &scrnVRes); /* if needed for defaults */
-
- /*
- * Read in header and Tags
- */
-
- if (TReadHeader(refNum, &dirOffset, &byteOrder) != noErr) {
- ErrorMessage(BADREADHEADER);
- return(false);
- }
-
- if(TReadTags(refNum, byteOrder,
- &listH, dirOffset, &nextDirOffset) != noErr) {
- ErrorMessage(BADREADTAGS);
- return(false);
- }
-
- /*
- * Get tags values.
- */
- /* SUBFILE_TYPE_TAG */
- if (TFindTag(listH, &tagOffset, SUBFILE_TYPE_TAG))
- TGetTag(listH, tagOffset, &id.subfileType, sizeof(id.subfileType));
- else {
- ErrorMessage(BADTIFF);
- CleanUp(listH, &id);
- return(false);
- }
- /* IMAGE_WIDTH_TAG */
- if (TFindTag(listH, &tagOffset, IMAGE_WIDTH_TAG))
- TGetTag(listH, tagOffset, &id.imageWidth, sizeof(id.imageWidth));
- else {
- ErrorMessage(BADTIFF);
- CleanUp(listH, &id);
- return(false);
- }
- /* IMAGE_LENGTH_TAG */
- if (TFindTag(listH, &tagOffset, IMAGE_LENGTH_TAG))
- TGetTag(listH, tagOffset, &id.imageLength, sizeof(id.imageLength));
- else {
- ErrorMessage(BADTIFF);
- CleanUp(listH, &id);
- return(false);
- }
- /* ROWS_PER_STRIP_TAG */
- if (TFindTag(listH, &tagOffset, ROWS_PER_STRIP_TAG)) {
- TGetTag(listH, tagOffset, &id.rowsPerStrip, sizeof(id.rowsPerStrip));
- tagDirEntry = GetDirEntry(listH, tagOffset);
- switch(tagDirEntry.type) {
- case LONG:
- break;
- case SHORT: /* ok, but convert returned value */
- id.rowsPerStrip = (long)( *((Int16 *)(&id.rowsPerStrip)) );
- break;
- default:
- ErrorMessage(BADTIFF);
- CleanUp(listH, &id);
- return(false);
- }
- }
- else {
- id.rowsPerStrip = INFINITY;
- }
- /* SAMPLES_PER_PIXEL_TAG */
- if (TFindTag(listH, &tagOffset, SAMPLES_PER_PIXEL_TAG))
- TGetTag(listH, tagOffset, &id.samplesPerPixel, sizeof(id.samplesPerPixel));
- else {
- id.samplesPerPixel = 1;
- }
- /* BITS_PER_SAMPLE_TAG */
- id.bitsPerSample = SetIDPtr(listH, BITS_PER_SAMPLE_TAG, 1L, SHORT);
- if (id.bitsPerSample == nil) {
- CleanUp(listH, &id);
- return(false);
- }
- /* PLANAR_CONFIG_TAG */
- if (TFindTag(listH, &tagOffset, PLANAR_CONFIG_TAG))
- TGetTag(listH, tagOffset, &id.planarConfig, sizeof(id.planarConfig));
- else
- id.planarConfig = 1;
- /* COMPRESSION_TAG */
- id.compression = SetIDPtr(listH, COMPRESSION_TAG, 1L, SHORT);
- if (id.compression == nil) {
- CleanUp(listH, &id);
- return(false);
- }
- /* MIN_SAMPLE_VALUE_TAG */
- id.minSampleValue = SetIDPtr(listH, MIN_SAMPLE_VALUE_TAG, 0L, SHORT);
- if (id.minSampleValue == nil) {
- CleanUp(listH, &id);
- return(false);
- }
- /* MAX_SAMPLE_VALUE_TAG */
- id.maxSampleValue = SetIDPtr(listH, MAX_SAMPLE_VALUE_TAG,
- (Int32)((1 << *id.bitsPerSample) - 1), SHORT);
- if (id.maxSampleValue == nil) {
- CleanUp(listH, &id);
- return(false);
- }
- /* PHOTOMETRIC_INTERP_TAG */
- if (TFindTag(listH, &tagOffset, PHOTOMETRIC_INTERP_TAG))
- TGetTag(listH, tagOffset, &id.photoInterp, sizeof(id.photoInterp));
- else {
- id.photoInterp = 0; /* assume mac photometric interpretation */
- }
- /* FILL_ORDER_TAG */
- if (TFindTag(listH, &tagOffset, FILL_ORDER_TAG))
- TGetTag(listH, tagOffset, &id.fillOrder, sizeof(id.fillOrder));
- else
- id.fillOrder = 1;
- /* ORIENTATION_TAG */
- if (TFindTag(listH, &tagOffset, ORIENTATION_TAG))
- TGetTag(listH, tagOffset, &id.orientation, sizeof(id.orientation));
- else
- id.orientation = 1;
- /* X_RESOLUTION_TAG */
- if (TFindTag(listH, &tagOffset, X_RESOLUTION_TAG))
- TGetTag(listH, tagOffset, &id.xResolution, sizeof(id.xResolution));
- else {
- id.xResolution.numerator = (Int32)scrnHRes;
- id.xResolution.denominator = 1;
- }
- /* Y_RESOLUTION_TAG */
- if (TFindTag(listH, &tagOffset, Y_RESOLUTION_TAG))
- TGetTag(listH, tagOffset, &id.yResolution, sizeof(id.yResolution));
- else {
- id.yResolution.numerator = (Int32)scrnVRes;
- id.yResolution.denominator = 1;
- }
-
- /*
- * Initialize of non-tag values.
- */
- oddRowBytes = (((id.imageWidth * (*id.bitsPerSample)) + 7) / 8) % 2 != 0;
- id.stripsPerImage =
- (id.imageLength + id.rowsPerStrip - 1) / id.rowsPerStrip;
-
- /*
- * Check Tag Values to see if we can read this TIFF file.
- *
- * NOTE: Although the majority of the tag were read, all the values
- * obtained are not used in displaying the image in THIS PROGRAM.
- * Those not used were read in simply for to provide the example.
- */
- DBG(DisplayID(&id));
- DBG(DebugMessage("image row bytes %ld",
- ((id.imageWidth * (*id.bitsPerSample + 7)) / 8)));
- DBG(DebugMessage("oddRowBytes=%s", oddRowBytes ? "true" : "false"));
- if ( (id.samplesPerPixel != 1) ||
- (*id.bitsPerSample != 1) ||
- (id.planarConfig != 1 && id.planarConfig != 2) ) {
- ErrorMessage(BADTIFF);
- CleanUp(listH, &id);
- return(false);
- }
- if (id.photoInterp != 0) /* We don't translate yet so let 'em know */
- ErrorMessage(BADPHOTOINTERP);
-
- rowBytes = (((id.imageWidth - 1) / (2 * 8)) + 1) * 2;
- /* only make image as much as will fit in MAXIMAGESIZE for now */
- size = id.imageLength * rowBytes;
- if (size > MAXIMAGESIZE) {
- ErrorMessage(IMAGECROPWARN);
- size = MAXIMAGESIZE;
- }
- rowsPerImage = size / rowBytes;
-
- /*
- * Prepare bitmap.
- */
- if (myBitMapPtr->baseAddr != nil)
- DisposPtr(myBitMapPtr->baseAddr);
- if ((myBitMapPtr->baseAddr = MyNewPtr(size)) == nil) {
- CleanUp(listH, &id);
- return(false);
- }
- myBitMapPtr->rowBytes = rowBytes;
- myBitMapPtr->bounds.top = 0;
- myBitMapPtr->bounds.left = 0;
- myBitMapPtr->bounds.bottom = rowsPerImage;
- myBitMapPtr->bounds.right = id.imageWidth;
-
-
- /*
- * Read in image.
- */
- DBG(DebugMessage("rowsPerImage=%ld",rowsPerImage));
- if (TReadImage(refNum, listH,
- 0L, myBitMapPtr->baseAddr, rowsPerImage, -1) != noErr) {
- CleanUp(listH, &id);
- return(false);
- }
- if (oddRowBytes)
- TFixOddRowBytes(myBitMapPtr);
- DisplayImage(FrontWindow(), myBitMapPtr);
-
- CleanUp(listH, &id);
- return(true);
- }
-
- void WriteTiff(refNum, myBitMapPtr)
- Int16 refNum;
- BitMap *myBitMapPtr;
- {
- Handle listH;
- Ptr bufferPtr;
- Boolean oddRowBytes;
- Int8 dummy;
- Int16 byteOrder,
- subfileType,
- imageWidth,
- imageLength,
- fillOrder,
- compressType,
- photoInterp,
- bitsPerPixel,
- minSampleValue,
- maxSampleValue,
- orientation,
- tiffRowBytes, /* number of bytes per row in TIFF format */
- plane, /* dummy parameter for TWriteImageStrip */
- scrnHRes,
- scrnVRes;
- Int32 rowsPerStrip,
- nextFileFree, /* next free location in output file */
- startLine,
- numLines,
- dirOffset,
- count;
- Rational xRes,
- yRes;
- Rect imageRect;
-
- /* get a handle for the in memory tag list */
- listH = NewHandle(0);
- if (MemError() != noErr) {
- ErrorMessage(BADMEMORY);
- return;
- }
-
- ScreenRes(&scrnHRes, &scrnVRes);
- imageRect = myBitMapPtr->bounds;
- /* write out 8 rows per strip - 8 is an arbitrary number */
- rowsPerStrip = MIN(imageRect.bottom - imageRect.top, 8);
-
- /* initialize tag values */
- byteOrder = MOTOROLA;
- subfileType = 1;
- imageWidth = imageRect.right;
- imageLength = imageRect.bottom;
- bitsPerPixel = 1;
- fillOrder = 1;
- compressType = 1;
- photoInterp = 0;
- minSampleValue = 0;
- maxSampleValue = (1 << bitsPerPixel) - 1;
- orientation = 1;
- xRes.numerator = (Int32)scrnHRes;
- xRes.denominator = 1;
- yRes.numerator = (Int32)scrnVRes;
- yRes.denominator = 1;
-
- tiffRowBytes = (imageRect.right * bitsPerPixel + 7) / 8;
- oddRowBytes = (tiffRowBytes % 2) != 0;
- DBG(DebugMessage("tiffRowBytes=%d oddRowBytes=%s",
- tiffRowBytes, oddRowBytes == false ? "false" : "true"));
-
- /*
- * Put tags in memory list.
- * The order tags are put in the list with TPutPtrTag is NOT important.
- */
- if ( TPutPtrTag(listH, SUBFILE_TYPE_TAG, SHORT,
- 1L, &subfileType) != noErr ||
- TPutPtrTag(listH, IMAGE_WIDTH_TAG, SHORT,
- 1L, &imageWidth) != noErr ||
- TPutPtrTag(listH, IMAGE_LENGTH_TAG, SHORT,
- 1L, &imageLength) != noErr ||
- TPutPtrTag(listH, ROWS_PER_STRIP_TAG, LONG,
- 1L, &rowsPerStrip) != noErr ||
- TPutPtrTag(listH, X_RESOLUTION_TAG, RATIONAL,
- 1L, &xRes) != noErr ||
- TPutPtrTag(listH, Y_RESOLUTION_TAG, RATIONAL,
- 1L, &yRes) != noErr ||
- TPutPtrTag(listH, BITS_PER_SAMPLE_TAG, SHORT,
- 1L,&bitsPerPixel) != noErr ||
- TPutPtrTag(listH, COMPRESSION_TAG, SHORT,
- 1L, &compressType) != noErr ||
- TPutPtrTag(listH, FILL_ORDER_TAG, SHORT,
- 1L, &fillOrder) != noErr ||
- TPutPtrTag(listH, ORIENTATION_TAG, SHORT,
- 1L, &orientation) != noErr ||
- TPutPtrTag(listH, PHOTOMETRIC_INTERP_TAG, SHORT,
- 1L, &photoInterp) != noErr ) {
- ErrorMessage(BADPUTTAGS);
- return;
- }
-
- /* leave room for header in output file */
- SetEOF(refNum, (Int32)sizeof(TiffHeader));
- nextFileFree = sizeof(TiffHeader);
-
- /*
- * Write out image to file, fixing from Macintosh rounding of rows to the
- * nearest 2 bytes, to the TIFF rounding of rows to the nearest byte.
- */
- if (oddRowBytes)
- TUnfixOddRowBytes(myBitMapPtr); /* round rows to nearest byte */
-
- startLine = 0;
- bufferPtr = myBitMapPtr->baseAddr;
- while (startLine < imageLength) {
- numLines = MIN(imageLength - startLine, rowsPerStrip);
- if (TWriteImageStrip(refNum, &nextFileFree, listH,
- startLine, numLines, bufferPtr, plane) != noErr) {
- ErrorMessage(BADWRITEIMAGE);
- return;
- }
- startLine += numLines;
- bufferPtr += numLines * tiffRowBytes;
- }
-
- if (oddRowBytes)
- TFixOddRowBytes(myBitMapPtr); /* round rows to nearest word */
-
- /* directory must be on word boundary */
- if (nextFileFree % 2 != 0) {
- /* add filler byte */
- count = 1;
- if (FSWrite(refNum, &count, &dummy) != noErr) {
- ErrorMessage(BADWRITE);
- return;
- }
- nextFileFree++;
- }
-
- dirOffset = nextFileFree;
-
- if (TWriteTags(refNum, byteOrder, &nextFileFree, listH, 0L) != noErr) {
- ErrorMessage(BADWRITETAGS);
- return;
- }
- if (TWriteHeader(refNum, dirOffset, byteOrder) != noErr) {
- ErrorMessage(BADWRITEHEADER);
- }
- }
-
- /*
- * Free the list handle and any memory allocated to image description structure.
- */
- static void CleanUp(listHandle, idPtr)
- Handle listHandle;
- id *idPtr;
- {
- MyDisposPtr(&idPtr->bitsPerSample);
- MyDisposPtr(&idPtr->compression);
- MyDisposPtr(&idPtr->docName);
- MyDisposPtr(&idPtr->imageDescription);
- MyDisposPtr(&idPtr->make);
- MyDisposPtr(&idPtr->model);
- MyDisposPtr(&idPtr->stripOffsets);
- MyDisposPtr(&idPtr->stripByteCounts);
- MyDisposPtr(&idPtr->minSampleValue);
- MyDisposPtr(&idPtr->maxSampleValue);
- MyDisposPtr(&idPtr->pageName);
- MyDisposPtr(&idPtr->freeOffsets);
- MyDisposPtr(&idPtr->freeByteCounts);
- MyDisposPtr(&idPtr->grayResponseCurve);
- MyDisposPtr(&idPtr->colorResponseCurves);
- DisposHandle(listHandle);
- }
-
- void InitID(idPtr)
- id *idPtr;
- {
- idPtr->subfileType = -1;
- idPtr->imageWidth = 0;
- idPtr->imageLength = 0;
- idPtr->bitsPerSample = nil;
- idPtr->compression = nil;
- idPtr->photoInterp = -1;
- idPtr->threshholding = -1;
- idPtr->cellWidth = -1;
- idPtr->cellLength = -1;
- idPtr->fillOrder = 0;
- idPtr->docName = nil;
- idPtr->imageDescription = nil;
- idPtr->make = nil;
- idPtr->model = nil;
- idPtr->stripOffsets = nil;
- idPtr->orientation = -1;
- idPtr->samplesPerPixel = 0;
- idPtr->rowsPerStrip = 0;
- idPtr->stripsPerImage = 0;
- idPtr->stripByteCounts = nil;
- idPtr->minSampleValue = nil;
- idPtr->maxSampleValue = nil;
- idPtr->xResolution.numerator = 0;
- idPtr->xResolution.denominator = 0;
- idPtr->yResolution.numerator = 0;
- idPtr->yResolution.denominator = 0;
- idPtr->planarConfig = -1;
- idPtr->pageName = nil;
- idPtr->xPosition.numerator = 0;
- idPtr->xPosition.denominator = 0;
- idPtr->yPosition.numerator = 0;
- idPtr->yPosition.denominator = 0;
- idPtr->freeOffsets = nil;
- idPtr->freeByteCounts = nil;
- idPtr->grayResponseUnit = -1;
- idPtr->grayResponseCurve = nil;
- idPtr->group3Options = 0;
- idPtr->group4Options = 0;
- idPtr->resolutionUnit = -1;
- idPtr->pageNumber[0] = 0;
- idPtr->pageNumber[1] = 0;
- idPtr->colorResponseUnit = -1;
- idPtr->colorResponseCurves = nil;
- }
-
- TiffDirEntry GetDirEntry(listHandle, tagOffset)
- Handle listHandle;
- Int32 tagOffset;
- {
- Ptr p;
-
-
- /* get pointer to tag list */
- p = &(**listHandle); /* HANDLE DEREFERENCE */
- /* get pointer to our tag's directory entry */
- p += tagOffset;
- /* return the whole Directory Entry Structure, not a pointer to it */
- return(*((TiffDirEntry *)p));
- }
-
-
- Int16 TypeSize(type)
- Int16 type;
- {
- switch (type) {
- case BYTE:
- return(BYTESIZE);
- case ASCII:
- return(ASCIISIZE);
- case SHORT:
- return(SHORTSIZE);
- case LONG:
- return(LONGSIZE);
- case RATSIZE:
- return(RATSIZE);
- }
- }
-
- Ptr SetIDPtr(listHandle, tag, defaultValue, defaultType)
- Handle listHandle;
- Int16 tag;
- Int32 defaultValue; /* won't handle defaults larger than 4 bytes */
- Int32 defaultType;
- {
- TiffDirEntry tagDE;
- Ptr p;
- Int32 tagOffset,
- size,
- nvals;
-
- if (TFindTag(listHandle, &tagOffset, tag)) {
- tagDE = GetDirEntry(listHandle, tagOffset);
- size = TypeSize(tagDE.type) * tagDE.length;
- if ((p = MyNewPtr(size)) != nil)
- TGetTag(listHandle, tagOffset, p, size);
- }
- else if (defaultType != 0) {
- if ((p = MyNewPtr(defaultType)) != nil) {
- switch (defaultType) {
- case BYTE:
- *(unsigned char *)p = defaultValue;
- break;
- case ASCII:
- *(unsigned char *)p = defaultValue;
- break;
- case SHORT:
- *(unsigned short *)p = defaultValue;
- break;
- case LONG:
- *(unsigned long *)p = defaultValue;
- break;
- case RATIONAL:
- ((Rational *)p)->numerator = defaultValue;
- ((Rational *)p)->denominator = 1;
- break;
- }
- }
- }
- else
- p = nil;
- return(p);
- }
-
- #ifdef DEBUG
- DisplayID(idPtr)
- id *idPtr;
- {
- DebugMessage("subfileType=%ld imageWidth=%ld imageLength=%ld bitsPerSample=%ld",
- idPtr->subfileType,
- idPtr->imageWidth,
- idPtr->imageLength,
- idPtr->bitsPerSample != nil ? *idPtr->bitsPerSample : -1);
-
- DebugMessage("compression=%ld photoInterp=%ld threshholding=%ld cellWidth=%ld cellLength=%ld",
- idPtr->compression != nil ? *idPtr->compression : -1,
- idPtr->photoInterp,
- idPtr->threshholding,
- idPtr->cellWidth,
- idPtr->cellLength);
-
- DebugMessage("fillOrder=%ld docName=%s imageDescription=%s make=%s model=%s",
- idPtr->fillOrder,
- idPtr->docName,
- idPtr->imageDescription,
- idPtr->make,
- idPtr->model);
-
- /* idPtr->stripOffsets = nil; */
-
- DebugMessage("orientation=%ld samplesPerPixel=%ld rowsPerStrip=%ld stripsPerImage=%ld",
- idPtr->orientation,
- idPtr->samplesPerPixel,
- idPtr->rowsPerStrip != INFINITY ? idPtr->rowsPerStrip : -1,
- idPtr->stripsPerImage);
-
- /* idPtr->stripByteCounts = nil; */
-
- DebugMessage("minSampleValue=%ld maxSampleValue=%ld",
- idPtr->minSampleValue ? *idPtr->minSampleValue : -1,
- idPtr->maxSampleValue ? *idPtr->maxSampleValue : -1);
-
- DebugMessage("xRes=%ld/%ld yRes=%ld/%ld planarConfig=%ld",
- idPtr->xResolution.numerator,
- idPtr->xResolution.denominator,
- idPtr->yResolution.numerator,
- idPtr->yResolution.denominator,
- idPtr->planarConfig);
- /*
- idPtr->pageName = nil;
- idPtr->xPosition.numerator = 0;
- idPtr->xPosition.denominator = 0;
- idPtr->yPosition.numerator = 0;
- idPtr->yPosition.denominator = 0;
- idPtr->freeOffsets = nil;
- idPtr->freeByteCounts = nil;
- idPtr->grayResponseUnit = -1;
- idPtr->grayResponseCurve = nil;
- idPtr->group3Options = 0;
- idPtr->group4Options = 0;
- idPtr->resolutionUnit = -1;
- idPtr->pageNumber[0] = 0;
- idPtr->pageNumber[1] = 0;
- idPtr->colorResponseUnit = -1;
- idPtr->colorResponseCurves = nil;
- */
- }
- #endif